﻿namespace SaveALot.CustomTaskCreate
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Workflow.Activities;
    using System.Workflow.ComponentModel;

    using Microsoft.SharePoint;

    public partial class StoreTaskCreation : SequenceActivity
    {
        #region Fields

        public static DependencyProperty StoreIDProperty = DependencyProperty.Register
          ( "StoreID", typeof( string ), typeof( StoreTaskCreation ) );
        public static DependencyProperty StoreTypeProperty = DependencyProperty.Register
        ( "StoreType", typeof( string ), typeof( StoreTaskCreation ) );
        public static DependencyProperty StoreUrlProperty = DependencyProperty.Register
          ( "StoreUrl", typeof( string ), typeof( StoreTaskCreation ) );

        #endregion Fields

        #region Constructors

        public StoreTaskCreation( )
        {
            InitializeComponent( );
        }

        #endregion Constructors

        #region Properties

        [Category( "Custom Save-A-Lot Actions" ),
        Browsable( true )]
        [DesignerSerializationVisibility( DesignerSerializationVisibility.Visible )]
        public string StoreID
        {
            get
            {
                return ( ( string )
                    ( base.GetValue( StoreTaskCreation.StoreIDProperty ) ) );
            }
            set
            {
                base.SetValue( StoreTaskCreation.StoreIDProperty, value );
            }
        }

        [Category( "Custom Save-A-Lot Actions" ),
        Browsable( true )]
        [DesignerSerializationVisibility( DesignerSerializationVisibility.Visible )]
        public string StoreType
        {
            get
            {
                return ( ( string )
                    ( base.GetValue( StoreTaskCreation.StoreTypeProperty ) ) );
            }
            set
            {
                base.SetValue( StoreTaskCreation.StoreTypeProperty, value );
            }
        }

        [Category( "Custom Save-A-Lot Actions" ),
        Browsable( true )]
        [DesignerSerializationVisibility( DesignerSerializationVisibility.Visible )]
        public string StoreUrl
        {
            get
            {
                return ( ( string )
                    ( base.GetValue( StoreTaskCreation.StoreUrlProperty ) ) );
            }
            set
            {
                base.SetValue( StoreTaskCreation.StoreUrlProperty, value );
            }
        }

        #endregion Properties

        #region Methods

        public static DateTime AddBusinessDays( DateTime date, int days )
        {
            int direction = ( days < 0 ) ? -1 : 1;

            while ( days != 0 )
            {
                date = date.AddDays( direction );
                if ( date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday )
                {
                    days -= direction;
                }
            }

            return date;
        }

        protected override ActivityExecutionStatus Execute( ActivityExecutionContext executionContext )
        {
            DateTime targetDate = new DateTime( );
            DateTime midDate = new DateTime( );

            DateTime currentRunningDate = new DateTime( );
            DateTime phaseCompletionDate = new DateTime( );
            string storeTitle = "";
            string taskOwner = "";
            int totalTaskDuration = 0;
            int realTaskDuration = 0;

            try
            {
                using ( SPSite storeSite = new SPSite( StoreUrl ) )
                {
                    using ( SPWeb storeWeb = storeSite.OpenWeb( ) )
                    {
                        SPList activeTaskList = storeWeb.Lists[ GetListNames( StoreType )[ 0 ] ];
                        SPList storesList = storeWeb.Lists[ GetListNames( StoreType )[ 1 ] ];
                        SPList staticPLTasksList = storeWeb.Lists[ GetListNames( StoreType )[ 2 ] ];
                        SPList staticBNTasksList = storeWeb.Lists[ GetListNames( StoreType )[ 3 ] ];
                        //List used to calculate and hold dates...
                        SPList dateHolderList = storeWeb.Lists[ "Date Calculations" ];

                        SPQuery storeQuery = new SPQuery( );
                        storeQuery.Query = "<Where><Eq><FieldRef Name='ID' /><Value Type='Counter'>" + StoreID.Trim( ) + "</Value></Eq></Where>";

                        SPQuery taskSortQuery = new SPQuery( );
                        taskSortQuery.Query = "<OrderBy><FieldRef Name='RefSort' Ascending='True' /></OrderBy>";

                        SPListItemCollection storeRecord = storesList.GetItems( storeQuery );
                        if ( storeRecord.Count == 0 )
                            throw new Exception( "No Corresponding Store Record Found" );

                        SPListItem singleStoreItem = storeRecord[ 0 ];
                        SPListItemCollection fixedSortedPLTasks = staticPLTasksList.GetItems( taskSortQuery );
                        SPListItemCollection fixedSortedBNTasks = staticBNTasksList.GetItems( taskSortQuery );

                        currentRunningDate = DateTime.Now;
                        storeTitle = singleStoreItem[ "Title" ].ToString( );

                        int plCounter = 0;
                        int bnCounter = 0;
                        int lastPLTask = fixedSortedPLTasks.Count;
                        int lastBNTask = fixedSortedBNTasks.Count;

                        //Add all Pipeline Tasks...
                        foreach ( SPListItem staticItem in fixedSortedPLTasks )
                        {
                            plCounter += 1;
                            SPListItem item = activeTaskList.Items.Add( );

                            item[ "Title" ] = storeTitle;
                            SPFieldLookupValue owner = new SPFieldLookupValue( staticItem[ "Task Owner Name" ].ToString( ) );
                            taskOwner = owner.LookupValue;
                            if ( singleStoreItem.Fields.ContainsField( taskOwner ) &&
                                singleStoreItem[ taskOwner ] != null )
                                item[ "Task Owner Name" ] = LookupStringClean( singleStoreItem[ taskOwner ].ToString( ) );

                            item[ "Store Number" ] = singleStoreItem[ "Store Number" ];
                            item[ "Reference #" ] = singleStoreItem[ "Reference #" ];
                            item[ "Task Reference Number" ] = staticItem[ "Ref Number" ];
                            item[ "Task Description" ] = staticItem[ "Task Description" ];
                            item[ "Task Group" ] = staticItem[ "Task Group" ];
                            item[ "Task Phase" ] = staticItem[ "Phase" ];
                            item[ "Store Task Type" ] = staticItem[ "Task Type" ];
                            item[ "Store Record ID" ] = singleStoreItem[ "Reference #" ];
                            item[ "Distribution Center" ] = singleStoreItem[ "Distribution Center" ];
                            item[ "Owner" ] = singleStoreItem[ "Owner" ];
                            item[ "Project Type" ] = singleStoreItem[ "Project Type" ];
                            item[ "Store Type" ] = singleStoreItem[ "Store Type" ];
                            item[ "Store State" ] = singleStoreItem[ "Store State" ];
                            item[ "Team" ] = singleStoreItem[ "Team" ];

                            if ( singleStoreItem[ "District Manager" ] != null )
                                item[ "District Manager" ] = LookupStringClean( singleStoreItem[ "District Manager" ].ToString( ) );

                            totalTaskDuration = int.Parse( staticItem[ "Task Duration" ].ToString( ) );
                            realTaskDuration = int.Parse( staticItem[ "Real Duration" ].ToString( ) );

                            item[ "Target Start Date" ] = currentRunningDate.ToShortDateString( );

                            if ( staticItem[ "Task Type" ].ToString( ).ToUpper( ).Trim( ).Equals( "MILESTONE" ) )
                                targetDate = AddBusinessDays( currentRunningDate, realTaskDuration );
                            else
                                targetDate = AddBusinessDays( currentRunningDate, realTaskDuration );

                            item[ "Target Completion Date" ] = targetDate.ToShortDateString( );

                            midDate = AddBusinessDays( targetDate, 0 - ( realTaskDuration / 2 ) );

                            if ( staticItem[ "Task Type" ] != null )
                                if ( staticItem[ "Task Type" ].ToString( ).ToUpper( ).Trim( ).Equals( "MILESTONE" ) )
                                    currentRunningDate = targetDate;

                            item[ "Midway Check Point" ] = midDate.ToShortDateString( );
                            item[ "Reportable" ] = staticItem[ "Reportable" ];

                            if ( plCounter == lastPLTask )
                            {
                                item[ "Last Task Flag" ] = "TRUE";
                                phaseCompletionDate = targetDate;
                            }

                            item.Update( );

                            //Create Date Tracking Record
                            SPListItem dateListItem = dateHolderList.Items.Add( );
                            dateListItem[ "Title" ] = "Old Date";
                            dateListItem[ "Task ID" ] = item[ "ID" ];
                            dateListItem[ "Store Type" ] = StoreType;
                            dateListItem[ "Task Type" ] = item[ "Store Task Type" ];
                            dateListItem[ "Store Number" ] = StoreID;
                            dateListItem[ "Old Date" ] = item[ "Target Completion Date" ];
                            dateListItem.Update( );
                        }

                        using ( SPWeb storeWeb2 = storeSite.OpenWeb( ) )
                        {
                            SPList activeTaskList2 = storeWeb.Lists[ GetListNames( StoreType )[ 0 ] ];
                            SPQuery storeTasksQuery = new SPQuery( );
                            storeTasksQuery.Query = "<Where><And><Eq><FieldRef Name='Store_x0020_Record_x0020_ID' /><Value Type='Number'>" + StoreID.Trim( ) + "</Value></Eq><Eq><FieldRef Name='Task_x0020_Phase' /><Value Type='Choice'>P1</Value></Eq></And></Where>";

                            SPListItemCollection storeTaskRecords = activeTaskList2.GetItems( storeTasksQuery );

                            foreach ( SPListItem item in storeTaskRecords )
                            {
                                item[ "Phase Completion Date" ] = phaseCompletionDate.ToShortDateString( );
                                item.Update( );
                            }
                        }

                        //Add all the Breaking News tasks...
                        foreach ( SPListItem staticItem in fixedSortedBNTasks )
                        {
                            bnCounter += 1;
                            SPListItem item = activeTaskList.Items.Add( );

                            item[ "Title" ] = storeTitle;
                            SPFieldLookupValue owner = new SPFieldLookupValue( staticItem[ "Task Owner Name" ].ToString( ) );
                            taskOwner = owner.LookupValue;
                            if ( singleStoreItem.Fields.ContainsField( taskOwner ) &&
                                singleStoreItem[ taskOwner ] != null )
                                item[ "Task Owner Name" ] = LookupStringClean( singleStoreItem[ taskOwner ].ToString( ) );

                            item[ "Store Number" ] = singleStoreItem[ "Store Number" ];
                            item[ "Reference #" ] = singleStoreItem[ "Reference #" ];
                            item[ "Task Reference Number" ] = staticItem[ "Ref Number" ];
                            item[ "Task Description" ] = staticItem[ "Task Description" ];
                            item[ "Task Group" ] = staticItem[ "Task Group" ];
                            item[ "Task Phase" ] = staticItem[ "Phase" ];
                            item[ "Store Task Type" ] = staticItem[ "Task Type" ];
                            item[ "Store Record ID" ] = singleStoreItem[ "Reference #" ];

                            item[ "Distribution Center" ] = singleStoreItem[ "Distribution Center" ];
                            item[ "Owner" ] = singleStoreItem[ "Owner" ];
                            item[ "Project Type" ] = singleStoreItem[ "Project Type" ];
                            item[ "Store Type" ] = singleStoreItem[ "Store Type" ];
                            item[ "Store State" ] = singleStoreItem[ "Store State" ];
                            item[ "Team" ] = singleStoreItem[ "Team" ];
                            if ( singleStoreItem[ "District Manager" ] != null )
                                item[ "District Manager" ] = LookupStringClean( singleStoreItem[ "District Manager" ].ToString( ) );

                            totalTaskDuration = int.Parse( staticItem[ "Task Duration" ].ToString( ) );
                            realTaskDuration = int.Parse( staticItem[ "Real Duration" ].ToString( ) );

                            item[ "Target Start Date" ] = currentRunningDate.ToShortDateString( );

                            if ( staticItem[ "Task Type" ].ToString( ).ToUpper( ).Trim( ).Equals( "MILESTONE" ) )
                                targetDate = AddBusinessDays( currentRunningDate, realTaskDuration );
                            else
                                targetDate = AddBusinessDays( currentRunningDate, realTaskDuration );

                            item[ "Target Completion Date" ] = targetDate.ToShortDateString( );

                            midDate = AddBusinessDays( targetDate, 0 - ( realTaskDuration / 2 ) );

                            if ( staticItem[ "Task Type" ] != null )
                                if ( staticItem[ "Task Type" ].ToString( ).ToUpper( ).Trim( ).Equals( "MILESTONE" ) )
                                    currentRunningDate = targetDate;

                            item[ "Midway Check Point" ] = midDate.ToShortDateString( );
                            item[ "Reportable" ] = staticItem[ "Reportable" ];

                            if ( bnCounter == lastBNTask )
                            {
                                item[ "Last Task Flag" ] = "TRUE";
                                phaseCompletionDate = targetDate;
                            }

                            item.Update( );

                            //Create Date Tracking Record
                            SPListItem dateListItem = dateHolderList.Items.Add( );
                            dateListItem[ "Title" ] = "Old Date";
                            dateListItem[ "Task ID" ] = item[ "ID" ];
                            dateListItem[ "Store Type" ] = StoreType;
                            dateListItem[ "Task Type" ] = item[ "Store Task Type" ];
                            dateListItem[ "Store Number" ] = StoreID;
                            dateListItem[ "Old Date" ] = item[ "Target Completion Date" ];
                            dateListItem.Update( );
                        }

                        using ( SPWeb storeWeb3 = storeSite.OpenWeb( ) )
                        {
                            SPList activeTaskList3 = storeWeb.Lists[ GetListNames( StoreType )[ 0 ] ];
                            SPQuery storeTasksQuery3 = new SPQuery( );
                            storeTasksQuery3.Query = "<Where><And><Eq><FieldRef Name='Store_x0020_Record_x0020_ID' /><Value Type='Number'>" + StoreID.Trim( ) + "</Value></Eq><Eq><FieldRef Name='Task_x0020_Phase' /><Value Type='Choice'>P2</Value></Eq></And></Where>";

                            SPListItemCollection storeTaskRecords = activeTaskList3.GetItems( storeTasksQuery3 );

                            foreach ( SPListItem item in storeTaskRecords )
                            {
                                item[ "Phase Completion Date" ] = phaseCompletionDate.ToShortDateString( );
                                item.Update( );
                            }
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                EventLog.WriteEntry( "Task Creation Workflow", ex.ToString( ) );
            }

            return ActivityExecutionStatus.Closed;
        }

        private static string[] GetListNames( string storeType )
        {
            string[ ] listNames = new string[ 4 ];

            listNames[ 0 ] = "Stores and Tasks";
            listNames[ 1 ] = "Stores Detail";

            switch ( storeType )
            {
                case "Corporate":
                    {
                        listNames[ 2 ] = "Corporate Pipeline Tasks";
                        listNames[ 3 ] = "Corporate Breaking News Tasks";
                    }
                    break;

                case "Licensee":
                    {
                        listNames[ 2 ] = "Licensee Pipeline Tasks";
                        listNames[ 3 ] = "Licensee Breaking News Tasks";
                    }
                    break;

            }
            return listNames;
        }

        private string LookupStringClean( string input )
        {
            string result = "";
            try
            {
                result = input.Substring( input.IndexOf( ";#" ) + 2 );
            }
            catch
            {
                result = input;
            }

            return result;
        }

        #endregion Methods
    }
}